﻿/**
*    Copyright (C) 2008  Chase Kernan 
*    chase.kernan@gmail.com
*
*    This program is free software: you can redistribute it and/or modify
*    it under the terms of the GNU General Public License as published by
*    the Free Software Foundation, either version 3 of the License, or
*    (at your option) any later version.
*
*    This program is distributed in the hope that it will be useful,
*    but WITHOUT ANY WARRANTY; without even the implied warranty of
*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
*    GNU General Public License for more details.
*
*    You should have received a copy of the GNU General Public License
*    along with this program.  If not, see <http://www.gnu.org/licenses/>.
* 
**/

package com.chasekernan.hxnova.server.functions;

import com.chasekernan.hxnova.core.dataholders.Global;
import com.chasekernan.hxnova.core.fleets.Fleet;
import com.chasekernan.hxnova.core.fleets.Salvage;
import com.chasekernan.hxnova.core.stars.Star;
import com.chasekernan.hxnova.core.minerals.MineralSet;

class Scrapping {
    
    /**
        Scraps all fleets with a waypoint0 order of [ScrapFleet].
    **/
    public static function run() {
        var playerTechGains = new Array < Array < String >> ();
        for (player in Global.players.players) {
            playerTechGains.push(new Array<String>());
        }
        
        var fleets = new Array<Fleet>();
        for (f in Global.fleets) fleets.push(f);
        
        var i = fleets.length;
        while (i-- > 0) {
            var f = fleets[i];
            
            if (f.owner.id == Global.players.nullPlayer.id) continue;
            
            //enums are technically not supposed to be used in boolean logic,
            //but in this case, a bunch of empty cases would be pointless, so 
            //this uses a small hack to compare them.
            
            if (Std.string(f.waypoint0) == Std.string(Task.ScrapFleet)) {
                //get the multipliers given by the race
                var scrap = getScrapFor(f);
                var resources = scrap.resources;
                var minerals = scrap.minerals;
                
                //check if its in orbit of a planet.
                var orbitting = false;
                for (star in Global.stars) {
                    if (f.location.equals(star.location)) {
                        orbitting = true;
                        star.minerals.add(minerals);
                        star.additionalResources += resources;
                        break;
                    }
                }
                
                //TODO: Should race modifiers modify the amount of minerals in
                //salvage?
                if (!orbitting) {
                    Global.salvage.addParticle(new Salvage(minerals));
                }
                
                Global.fleets.removeParticle(f);
                
                //add tech
                for (field in f.getAdditionalTech(f.owner.techLevel)) {
                     if (!arrayContains(playerTechGains[f.owner.id], field)) {
                        playerTechGains[f.owner.id].push(field);
                     }
                }
                
                //randomly choose one for each player
                for (i in 0...Global.players.players.length) {
                    if (playerTechGains[i].length == 0) continue;
                    
                    //TODO: Stop [Player] from sending the default tech message
                    //and send one regarding scrapping instead.
                    f.owner.incrementTechField(playerTechGains[i]
                            [Std.random(playerTechGains[i].length)]);
                }
            }
        }
    }
    
    public static function getScrapFor(fleet : Fleet) : 
            { resources : Int, minerals : MineralSet } {
        var scrapMultipliers = fleet.owner.race.getScrap();
        var fleetScrap = fleet.getTotalCost();
                
        var resources = Std.int(fleetScrap.resources * 
                scrapMultipliers.resources);
        var minerals = fleetScrap.minerals.multiply(
                scrapMultipliers.minerals);
        
        return { resources : resources, minerals : minerals };
    }
    
    private static function arrayContains<T>(array : Array<T>, 
            value : T) : Bool {
        for (v in array) {
            if (v == value) return true;
        }
        return false;
    }
}